/*
 * Copyright (C) 2010 M. Hautle.
 * 
 * This file is part of SimpleEL.
 * 
 * SimpleEL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any later version.
 * 
 * SimpleEL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License along with SimpleEL. If not, see <http://www.gnu.org/licenses/>.
 */
package ch.simpleel.internal;

/**
 * Class recording an EL path per thread.<br>
 * 
 * @author hautle
 */
public class ELRecorder {
    /** The recorders, hold by thread. */
    private static final ThreadLocal<ELRecorder> RECORDER = new ThreadLocal<ELRecorder>() {
        @Override
        protected ELRecorder initialValue() {
            return new ELRecorder();
        };
    };

    /** The current path. */
    private final StringBuilder path = new StringBuilder();

    /**
     * Hidden constructor.
     */
    private ELRecorder() {
    }

    /**
     * Appends the given part to the path.
     * 
     * @param s The part to add
     */
    public static void append(String s) {
        RECORDER.get().append0(s);
    }

    /**
     * Returns the path of the recorded calls and resets the path.
     * 
     * @return The path as EL expression
     */
    public static String getPath() {
        final ELRecorder rec = RECORDER.get();
        final String res = rec.getPath0();
        rec.reset0();
        return res;
    }

    /**
     * Resets the recorded path.
     */
    public static void reset() {
        RECORDER.get().reset0();
    }

    /**
     * Records the given string.
     * 
     * @param s The string to record
     */
    private void append0(String s) {
        if (path.length() > 0)
            path.append('.');
        // figure out if this is a boolean property (isXyz) or a normal one (getXyz)
        final int index = s.charAt(0) == 'i' ? 2 : 3;
        final int second = index + 1;
        if (second < s.length() && Character.isUpperCase(s.charAt(second)) && Character.isUpperCase(s.charAt(index))) {
            // special name - property name starts with two upper case chars (maybe URL :) )
            path.append(s, index, s.length());
        } else {
            // first char of property name must be lower case
            path.append(Character.toLowerCase(s.charAt(index)));
            path.append(s, second, s.length());
        }
    }

    /**
     * Returns the path of the recorded calls.
     * 
     * @return The path as EL expression
     */
    private String getPath0() {
        return path.toString();
    }

    /**
     * Resets the path.
     */
    private void reset0() {
        path.setLength(0);
    }
}
